Reactivity in Svelte

Posted on 2023-02-02 by

henrikvilhelmberglund

In Svelte we can have something called Reactivity , basically meaning: When we update variables, update the DOM as well.

One way of achieving this is to simply assign a variable in the top level

0
<script>
  let count = 0;

  function increment() {
    count++;
  }
</script>

<div>{count}</div>

<button on:click={()=>increment()}>Click me</button>

The variable type doesn't really matter, but we do need to change the value using one of three methods.

  1. Assignment. count = 10;
  2. Update statements. count++;
  3. Updating/assigning a property. obj.count++;
0
<script>
  let obj = {
    count: 0
  };

  function increment() {
    obj.count++;
  }
</script>

<div>{obj.count}</div>

<button on:click={()=>increment()}>Click me</button>

Here are some of the things that will not trigger reactivity.

Don't do this

  1. Indirect object references
0
<script>
  let obj = {
    count: 0
  };
  let myObj = obj;
  
  function incrementWrong() {
    myObj.count++;
  }
  function assignToObj() {
    obj.foo = 1;
  }

</script>

<div>{obj.count}</div>

<button on:click={()=>incrementWrong()}>This does not update the DOM</button>
<button on:click={()=>assignToObj()}>But this will trigger the update (assigned in the function)</button>
  1. Array methods
[]
<script>
  let array = []

  function increment() {
    array.push(1);
  }
</script>

<div>{JSON.stringify(array)}</div>

<button on:click={()=>increment()}>Click me</button>

Instead: spread syntax

Instead of using array methods we can use spread syntax .

[]
<script>
  let array = []

  function increment() {
    array = [...array, 1];
  }
</script>

<div>{JSON.stringify(array)}</div>

<button on:click={()=>increment()}>Click me</button>

Or, we can just do array = array; . It is a bit ugly but it works!

[]
<script>
  let array = []

  function increment() {
    array.push(1);
    array = array;
  }
</script>

<div>{JSON.stringify(array)}</div>

<button on:click={()=>increment()}>Click me</button>